package com.tpvlog.im.dispatcher;

import com.tpvlog.im.common.Constants;
import com.tpvlog.im.common.Message;
import com.tpvlog.im.common.Request;
import com.tpvlog.im.common.Response;
import com.tpvlog.im.protocal.AuthenticateRequestProto;
import com.tpvlog.im.protocal.AuthenticateResponseProto;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;

public class DispatcherHandler extends ChannelInboundHandlerAdapter {

    /**
     * 一个Gateway接入系统跟分发系统建立了连接
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel channel = (SocketChannel) ctx.channel();
        // 缓存连接
        String channelId = channel.remoteAddress().getHostName() + ":" + channel.remoteAddress().getPort();
        GatewayInstanceManager.getInstance().addGatewayInstance(channelId, channel);
        System.out.println("已经跟IM-GATEWAY系统建立连接，地址为：" + channel.remoteAddress());
    }

    /**
     * 一个Gateway接入系统跟分发系统断开了连接
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel channel = (SocketChannel) ctx.channel();
        String channelId = channel.remoteAddress().getHostName() + ":" + channel.remoteAddress().getPort();
        GatewayInstanceManager.getInstance().removeGatewayInstance(channelId);
        System.out.println("已经跟IM-GATEWAY系统断开连接，地址为：" + channel);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        Message message = new Message((ByteBuf) msg);
        System.out.println("收到一条消息，消息类型为：" + message.getMessageType());
        // 1.如果是IM-GATEWAY系统的请求
        if (message.getMessageType() == Constants.MESSAGE_TYPE_REQUEST) {
            Request request = message.toRequest();
            // 认证请求
            if (request.getRequestType() == Constants.REQUEST_TYPE_AUTHENTICATE) {
                AuthenticateRequestProto.AuthenticateRequest authenticateRequest =
                        AuthenticateRequestProto.AuthenticateRequest.parseFrom(request.getBody());
                // 交给RequstHandler进行认证处理
                AuthenticateResponseProto.AuthenticateResponse authenticateResponse = RequestHandler.getInstance()
                        .authenticate(authenticateRequest);
                if (authenticateResponse.getStatus() == Constants.RESPONSE_STATUS_OK) {
                    SocketChannel socketChannel = (SocketChannel) ctx.channel();
                    String gatewayChannelId = socketChannel.remoteAddress().getHostName() + ":"
                            + socketChannel.remoteAddress().getPort();

                    // 将session信息写入Redis
                    String key = authenticateResponse.getUid();
                    String token = authenticateRequest.getToken();
                    long timestamp = authenticateRequest.getTimestamp();
                    // key=uid，value={
                    //      'token':'',
                    //      'timestamp':'',
                    //      'isAuthenticated':'true',
                    //      'authenticateTimestamp':'....',
                    //      'gatewayChannelId': ''
                    // }

                    System.out.println("在Redis中写入分布式Session......");
                }

                Response response = new Response(request, authenticateResponse.toByteArray());
                ctx.writeAndFlush(response.getBuffer());
                System.out.println("返回响应给IM-GATEWAY系统：" + authenticateResponse);
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
